from django import forms
from apps.web.forms.bootstrap import BootStrapForm
from apps.web import models
from django.core.exceptions import ValidationError
from tools import cos
from qcloud_cos.cos_exception import CosServiceError


class WikiModelForm(BootStrapForm, forms.ModelForm):
    bootstrap_class_exclude = []

    class Meta:
        # 指定模型类
        model = models.Wiki
        fields = ['title', 'content', 'parent']

    def __init__(self, request, *args, **kwargs):
        super().__init__(*args, **kwargs)
        total_data_list = [('', '请选择'), ]
        data_list = models.Wiki.objects.filter(project=request.tracer.project).values_list('id', 'title')
        total_data_list.extend(data_list)
        self.fields['parent'].choices = total_data_list


class FileModelForm(BootStrapForm, forms.ModelForm):
    # 指定模型类
    class Meta:
        model = models.FileRepository
        fields = ['name']

    def __init__(self, request, parent_obj, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.request = request
        self.parent_obj = parent_obj

    def clean_name(self):
        name = self.cleaned_data.get('name')
        # 去数据库检查当前目录下是否存在该名称文件夹
        queryset = models.FileRepository.objects.filter(file_type=2, name=name, project=self.request.tracer.project)
        # 若当前有父级目录
        if self.parent_obj:
            exists = queryset.filter(parent=self.parent_obj).exists()
        # 在根目录下
        else:
            exists = queryset.filter(parent__isnull=True).exists()
        if exists:
            raise ValidationError('当前目录下文件名已存在')
        return name


class PerFileModelForm(forms.ModelForm):
    etag = forms.CharField(
        label='ETag',
        max_length=128
    )

    def __init__(self, request, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.request = request

    class Meta:
        model = models.FileRepository
        exclude = ['project', 'file_type', 'update_user', 'update_datetime']

    def clean_file_path(self):
        return 'https://{}'.format(self.cleaned_data.get('file_path'))

    # 整体钩子
    def clean(self):
        key = self.cleaned_data.get('key')
        etag = self.cleaned_data.get('etag')
        if not key and not etag:
            return self.cleaned_data
        # 向cos校验Etag
        try:
            result = cos.check_file(self.request.tracer.project.region, self.request.tracer.project.bucket, key)

        except CosServiceError as e:
            self.add_error('key', '文件未上传成功')
            return self.cleaned_data
        cos_etag = result.get('ETag')
        if etag != cos_etag:
            self.add_error('etag', 'etag错误')

        if self.cleaned_data.get('file_size') != int(result.get('Content-Length')):
            self.add_error('file_size', '文件大小不一致')
        return self.cleaned_data
